﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Pout_Porri.Levels;
using Pout_Porri.Utils;

namespace Pout_Porri.Objects
{
    class World
    {
        /// <summary>
        /// The list of all game entitys in the game
        /// </summary>
        public static  List<GameEntity> gameEntitys;

        /// <summary>
        /// The size of the world
        /// </summary>
        private Vector2 dimensions;
        private PhysicsGameEntity worldActor;
        private Level level;

        /// <summary>
        /// World constructor
        /// </summary>
        /// <param name="level"> the current level of this world</param>
        /// <param name="dimensions">The size</param>
        public World(Level level,Vector2 dimensions)
        {
            gameEntitys = new List<GameEntity>();
            this.dimensions = dimensions;
            this.level = level;
        }

        public void setWorldActor(PhysicsGameEntity worldActor)
        {
            this.worldActor = worldActor;
        }

        public PhysicsGameEntity getWorldActor()
        {
            return this.worldActor;
        }

        public void addGameEntity(GameEntity gE)
        {
            gameEntitys.Add(gE);
        }

        public void removeGameEntity(GameEntity gE)
        {
            gameEntitys.Remove(gE);
        }


        /// <summary>
        /// Remove every game entity in the current level
        /// </summary>
        public void unloadWorld()
        {
            foreach (GameEntity ge in World.gameEntitys)
            {
                this.removeGameEntity(ge);
            }

        }

      
        /// <summary>
        /// Keep the game entity in the limits of the world
        /// </summary>
        /// <param name="gE">A game entity</param>
        private void keepInWorld(GameEntity gE)
        {
            if (gE is PhysicsGameEntity)
            {
                keepInWorldPhysicsEntity((PhysicsGameEntity)gE);
            }
            else
            {
                keepInWorldGameEntity(gE);
            }
        }

        private void keepInWorldPhysicsEntity(PhysicsGameEntity pGE)
        {
            if (pGE.CollisionRect.Right >= this.dimensions.X - pGE.CollisionRect.Width)
            {
                pGE.position.X = this.dimensions.X - pGE.CollisionRect.Width;
            }

            if (pGE.CollisionRect.Bottom >= this.dimensions.Y - pGE.CollisionRect.Height)
            {
                pGE.position.Y = this.dimensions.Y - pGE.CollisionRect.Height;
            }

            if (pGE.CollisionRect.Left <= 0)
            {
                pGE.position.X = 0;
            }

            if (pGE.CollisionRect.Top <= 0)
            {
                pGE.position.Y = 0;
            }
        }

        private void keepInWorldGameEntity(GameEntity gE)
        {
            if (gE.CollisionRect.Right >= this.dimensions.X - gE.CollisionRect.Width)
            {
                gE.position.X = this.dimensions.X - gE.CollisionRect.Width;
            }

            if (gE.CollisionRect.Bottom >= this.dimensions.Y - gE.CollisionRect.Height)
            {
                gE.position.Y = this.dimensions.Y - gE.CollisionRect.Height;
            }

            if (gE.CollisionRect.Left <= 0)
            {
                gE.position.X = 0;
            }

            if (gE.CollisionRect.Top <= 0)
            {
                gE.position.Y = 0;
            }
        }


        /// <summary>
        /// Indica se o player colidiu com as entidades
        /// </summary>
        public static bool isCollisionEntity = false;


        public static GameEntity entityCollided;

        /// <summary>
        /// Faz a colisão do plaer com as entidades
        /// </summary>
        public bool CollisionEntity()
        {
            foreach (PhysicsGameEntity pe in World.gameEntitys)
            {
                //Game1.window.Title = "" + this.worldActor.CollisionRect + " " + pe.CollisionRect;
                if (this.worldActor.isCollide(pe))
                {
                    if (pe.disablePixelCollision)  
                        continue;

                    if (pe is Rope)
                    {
                        entityCollided = pe;
                        return true;
                    }

                   
                    if (this.worldActor.currentAnimationRect != null && pe.currentAnimationRect != null)
                    {
                        if (this.worldActor.ColisaoPorPixel(this.worldActor,pe))
                        {
                            entityCollided = pe;
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public void update(GameTime gameTime)
        {
            this.worldActor.update(gameTime);

            if (CollisionEntity())
                isCollisionEntity = true;
            else
            isCollisionEntity = false;
            
            // update other entitys
            foreach (GameEntity gE in gameEntitys)
            {
                gE.update(gameTime);

                if (gE is PhysicsGameEntity)
                {
                    {
                        PhysicsGameEntity physicsEntity = ((PhysicsGameEntity)gE);
                        physicsEntity.applyGravity(gameTime);
                        if (gE.useKeepInWorld)
                            keepInWorld(physicsEntity);
                    }
                }
            }
            
        }

        public void draw(SpriteBatch spriteBatch)
        {
            worldActor.draw(spriteBatch);

            foreach (GameEntity gE in gameEntitys)
            {
                gE.draw(spriteBatch);
            }
        }
    }
}
